var data = require("./data.js");

var define = data.define;

var mouses = [];

function getMouseNumber() {
  return mouses.length;
}

function addMouse(map, mapW, mapH, width, mapMouse) {
  var m = {};
  while (1) {
    m.x = (Math.random() * 100).toFixed() % (mapH - 2) + 1;
    var i = 0;
    for (i = 0; i < mapH; i++) {
      m.y = (Math.random() * 100).toFixed() % (mapW - 2) + 1;
      if (!data.isWall(map[m.x][m.y]) && map[m.x][m.y] != define.Block)
        break;
    }
    if (i != mapW)
      break;
  }
  m.dir = (Math.random() * 100).toFixed() % 4;
  m.last_x = m.x;
  m.last_y = m.y;
  m.label = mouses.length;

  m.next_x =0;
  m.next_y = 0;
  m.next_dir=0;
  m.midX=0;
  m.midY=0;

  mouses.push(m);
  calNext(mouses.length - 1,map, mapW, mapH, width, mapMouse);
  show_mouse(m, map, mapW, mapH, width, mapMouse);
}

function show_mouse(m, map, mapW, mapH, width, mapMouse) {
  map[m.last_x][m.last_y] = 0;
  map[m.x][m.y] = m.dir + 2;
  mapMouse[m.last_x][m.last_y] = -1;
  mapMouse[m.x][m.y] = m.label;
}

function clear_mouse(m, map, mapW, mapH, width, mapMouse) {
  map[m.last_x][m.last_y] = 0;
  map[m.x][m.y] = 0;
  mapMouse[m.last_x][m.last_y] = -1;
  mapMouse[m.x][m.y] = -1;
}

function calNext(m, map, mapW, mapH, width, mapMouse)
{
  var dir_change_prob = 40;
  var dir_change = (Math.random() * 100) > dir_change_prob;
  var i = 0;
  if (!dir_change)
    mouses[m].next_dir = (2 + mouses[m].dir);//(Math.random() * 100).toFixed() %4

  for (i = 0; i < 4; i++) {
    var p = (mouses[m].next_dir + i) % 4;
    var tx = mouses[m].x + define.Dir[p][0];
    var ty = mouses[m].y + define.Dir[p][1];
    if (!data.isWall(map[tx][ty]) && map[tx][ty] != define.Block) {
      mouses[m].next_x = tx;
      mouses[m].next_y = ty;
      mouses[m].next_dir = p;
      break;
    }
  }
}

function move_mouse(m, map, mapW, mapH, width, mapMouse) {
  var dir_change_prob = 40;
  var dir_change = (Math.random() * 100) > dir_change_prob;
  var i = 0;
  if (!dir_change)
    mouses[m].dir += 2;//(Math.random() * 100).toFixed() %4

  mouses[m].last_x = mouses[m].x;
  mouses[m].last_y = mouses[m].y;

  for (i = 0; i < 4; i++) {
    var p = (mouses[m].dir + i) % 4;
    var tx = mouses[m].x + define.Dir[p][0];
    var ty = mouses[m].y + define.Dir[p][1];
    if (!data.isWall(map[tx][ty]) && map[tx][ty] != define.Block) {
      mouses[m].x = tx;
      mouses[m].y = ty;
      mouses[m].dir = p;
      break;
    }
  }
}

function createMouses(n, map, mapW, mapH, width, mapMouse) {
  for (var i = 0; i < n; i++)
    addMouse(map, mapW, mapH, width, mapMouse);
}

function updateOffset(i, interval, width) {
  // console.log("interval:",interval);
  // let step = parseInt((interval / define.MouseSpeed)*width/2);
  // mouses[i].midX = (mouses[i].next_x - mouses[i].x) * step;
  // mouses[i].midY = (mouses[i].next_y - mouses[i].y) * step;
}

function updateNow(i)
{
  mouses[i].last_x = mouses[i].x;
  mouses[i].last_y = mouses[i].y;
  mouses[i].x = mouses[i].next_x;
  mouses[i].y = mouses[i].next_y;
  mouses[i].dir = mouses[i].next_dir;
}


function updateMouses(interval, map, mapW, mapH, width, mapMouse) {
  for (var i = 0; i < mouses.length; i++) {
    if (interval != 0) {
      updateOffset(i, interval, width);
      continue;
    }
    else
    {
       updateNow(i);
       calNext(i, map, mapW, mapH, width, mapMouse);
    }
    //move_mouse(i, map, mapW, mapH, width, mapMouse);
    show_mouse(mouses[i], map, mapW, mapH, width, mapMouse);
  }
}

function delete_mouse(label, map, mapW, mapH, width, mapMouse) {
  for (var i = 0; i < mouses.length; i++) {
    if (mouses[i].label == label) {
      clear_mouse(mouses[i], map, mapW, mapH, width, mapMouse);
      mouses.splice(i, 1);
      break;
    }
  }
}

function clear() {
  mouses = [];
}

function getInfo() {
  return mouses;
}

module.exports = {
  delete_mouse: delete_mouse,
  updateMouses: updateMouses,
  createMouses: createMouses,
  getMouseNumber: getMouseNumber,
  clear: clear,
  getInfo: getInfo
}